package com.sharp.authorization.service.docking.utils;

import com.sharp.authorization.service.docking.dto.SignDTO;
import com.sharp.kernel.constant.err.ErrCodeSys;
import com.sharp.kernel.exception.ServiceException;
import com.sharp.kernel.utils.DateUtil;
import com.sharp.framework.utils.security.DesUtil;
import com.sharp.framework.utils.security.MD5Util;
import com.sharp.kernel.validate.Validator;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;
import java.util.UUID;

/**
 * Title: DockingSignUtil
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2021/6/10 15:30
 */
public class DockingSignUtil {

    public static void validateSign(long timeStamp, String nonce, String signature, String appSecret) {
        Date now = new Date();
        Date reqDate = new Date(timeStamp);
        int secondDiff = DateUtil.secondDiff(reqDate, now);
        Validator.assertFalse(Math.abs(secondDiff) > 600, ErrCodeSys.SYS_VALIDATE_NOT_PASS, "时间戳");
        String text = MD5Util.MD5(timeStamp + nonce).toUpperCase();
        if (StringUtils.isNotBlank(appSecret)) {
            try {
                String deCrypt = DesUtil.decrypt(signature, appSecret);
                Validator.assertTrue(StringUtils.equals(deCrypt, text), ErrCodeSys.SYS_VALIDATE_NOT_PASS, "签名");
            } catch (Exception e) {
                throw new ServiceException("鉴权失败");
            }
        } else {
            throw new ServiceException("秘钥信息不存在");
        }
    }

    public static SignDTO sign(String appSecret) {
        return sign(System.currentTimeMillis(), UUID.randomUUID().toString(), appSecret);
    }

    public static SignDTO sign(long timeStamp, String nonce, String secret) {
        SignDTO sign = new SignDTO();
        sign.setNonce(nonce);
        sign.setTimeStamp(timeStamp);
        String text = MD5Util.MD5(timeStamp + nonce).toUpperCase();
        if (StringUtils.isNotBlank(secret)) {
            try {
                sign.setSignature(DesUtil.encrypt(text, secret));
                return sign;
            } catch (Exception e) {
                throw new ServiceException("加密失败", e);
            }
        } else {
            throw new ServiceException("秘钥信息不存在");
        }
    }
}
